import React, { useEffect, useRef } from "react";
import styles from "./index.module.css";
import { useState } from "react";
export default function Index() {
  const canvas = useRef();
  const context = useRef();
  const graph = [];
  let clickX, clickY;
  let canvasInfo;
  let parentNode;
  const siderClick = useRef();
  const siderList = [
    {
      text: "无",
      type: null,
    },
    {
      text: "线条",
      type: "line",
    },
    {
      text: "矩形",
      type: "rect",
    },
  ];
  const [parentInfo, setParentInfo] = useState();
  useEffect(() => {
    /** @type {HTMLCanvasElement} */
    canvas.current = document.getElementById("canvascom");
    context.current = canvas.current.getContext("2d");
    canvasInfo = canvas.current.getBoundingClientRect();
    canvas.current.addEventListener("mousedown", mousedownFn);
    parentNode = canvas.current.parentNode;
    const parentNodeInfo = parentNode.getBoundingClientRect();
    setParentInfo(parentNodeInfo);
    draw();
    resizeFn();
  }, []);
  const resizeFn = () => {
    window.onresize = () => {
      const parentNodeInfo = parentNode.getBoundingClientRect();
      setParentInfo(parentNodeInfo);
    };
  };
  const mousedownFn = (event) => {
    clickX = event.clientX - canvasInfo.left;
    clickY = event.clientY - canvasInfo.top;
    const GraphItem = getGraph(clickX, clickY);
    console.log(GraphItem);
    if (GraphItem) {
      // 拖动
      const { startX, startY, endX, endY } = GraphItem;
      window.onmousemove = (e) => {
        const disX = e.clientX - canvasInfo.left - clickX;
        const disY = e.clientY - canvasInfo.top - clickY;
        GraphItem.startX = startX + disX;
        GraphItem.startY = startY + disY;
        GraphItem.endX = endX + disX;
        GraphItem.endY = endY + disY;
      };
    } else {
      // 增加
      const react = siderClickFN(siderClick.current, "red", clickX, clickY);
      if (!react) return;
      graph.push(react);
      window.onmousemove = (e) => mousemoveFn(e, react);
    }

    window.onmouseup = () => {
      window.onmousemove = null;
      window.onmouseup = null;
    };
  };
  const mousemoveFn = (event, react) => {
    const x = event.clientX - canvasInfo.left;
    const y = event.clientY - canvasInfo.top;
    if (react.type === "line") {
      react.pintList.push({
        moveX: x * devicePixelRatio,
        moveY: y * devicePixelRatio,
      });
    }
    if (react.type === "rect") {
      react.endX = x;
      react.endY = y;
    }
  };
  const draw = () => {
    context.current.clearRect(
      0,
      0,
      canvas.current.width,
      canvas.current.height
    );
    requestAnimationFrame(draw);
    graph.forEach((rect) => {
      rect.draw();
    });
  };
  const getGraph = (x, y) => {
    for (let i = graph.length - 1; i >= 0; i--) {
      if (graph[i].isSider?.(x, y) && graph[i].type !== "line") {
        return graph[i];
      }
    }
    return null;
  };
  class CreateRect {
    constructor(color, x, y) {
      this.color = color;
      this.startX = x * devicePixelRatio;
      this.startY = y * devicePixelRatio;
      this.endX = x * devicePixelRatio;
      this.endY = y * devicePixelRatio;
      this.type = "rect";
    }
    get minX() {
      return Math.min(this.startX, this.endX);
    }
    get minY() {
      return Math.min(this.startY, this.endY);
    }
    get maxX() {
      return Math.max(this.startX, this.endX);
    }
    get maxY() {
      return Math.max(this.startY, this.endY);
    }
    isSider(x, y) {
      return (
        x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY
      );
    }
    draw() {
      const ctx = context.current;
      ctx.beginPath();
      ctx.rect(
        this.startX,
        this.startY,
        this.endX - this.startX,
        this.endY - this.startY
      );
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.strokeStyle = "black";
      ctx.lineWidth = 1;
      ctx.stroke();
      ctx.closePath();
    }
  }
  class CreateLine {
    constructor(color, x, y) {
      this.color = color;
      this.type = "line";
      this.pintList = [
        {
          moveX: x * devicePixelRatio,
          moveY: y * devicePixelRatio,
        },
      ];
    }

    draw() {
      const ctx = context.current;
      ctx.beginPath();
      this.pintList.forEach((item, index) => {
        if (index === 0) {
          ctx.moveTo(item.moveX, item.moveY);
        } else {
          ctx.lineTo(item.moveX, item.moveY);
        }
      });
      ctx.strokeStyle = this.color;
      ctx.lineWidth = 2;
      ctx.stroke();
      ctx.closePath();
    }
  }
  const siderClickFN = (type, color, x, y) => {
    if (type === "line") {
      return new CreateLine(color, x, y);
    } else if (type === "rect") {
      return new CreateRect(color, x, y);
    }
  };
  return (
    <div className={styles.container}>
      <canvas
        id="canvascom"
        width={parentInfo?.width}
        height={parentInfo?.height}
        className={styles.myCanvas}
      ></canvas>
      <div className={styles.sider}>
        <div className={styles.list}>
          {siderList.map((item, index) => (
            <div
              key={index}
              className={styles.item}
              onClick={() => {
                siderClick.current = item.type;
              }}
            >
              {item.text}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
